using AnalyStock.DataManage;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace AnalyStock.WPFPage;

public partial class ClassifyStockPage : Page
{
    public ClassifyStockPage()
    {
        InitializeComponent();
        InitializeContextMenu();
        InitializeTreeView();
    }

    private void InitializeContextMenu()
    {
        ContextMenu _contextMenu = new()
        {
            Style = Application.Current.Resources["ContextMenuStyle"] as Style
        };
        MenuItem _menuItem_Expanded = new()
        {
            Header = "🔸全部折叠 ▷◁",
            Style = Application.Current.Resources["MenuItemStyle"] as Style
        };
        _menuItem_Expanded.Click += (s, e) => TreeViewChangeStatus();
        _contextMenu.Items.Add(_menuItem_Expanded);
        MenuItem _menuItem_Refresh = new()
        {
            Header = "🔸数据刷新 ▶▶",
            Style = Application.Current.Resources["MenuItemStyle"] as Style
        };
        _menuItem_Refresh.Click += async (s, e) => await FillTreeViewDataAsync();
        _contextMenu.Items.Add(_menuItem_Refresh);
        StocksNameTreeView.ContextMenu = _contextMenu;
    }

    private async void InitializeTreeView()
    {
        StocksNameTreeView.PreviewMouseDown += TreeView_PreviewMouseDown;
        StocksNameTreeView.MouseMove += TreeView_MouseMove;
        StocksNameTreeView.MouseUp += TreeView_MouseUp;
        StocksNameTreeView.MouseLeave += TreeView_MouseLeave;
        StocksNameTreeView.SelectedItemChanged += TreeView_Change;
        //自选股变化后触发事件
        ChartKline.Updated_SeleStock += RefershTreeViewItem;
        await FillTreeViewDataAsync();
    }

    private static async Task<IList<SelectStock>> FillSeleStocksAsync()
    {
        return await CommDataMethod<SelectStock>.GetDataOnDbSetAsync()
                                                .ConfigureAwait(false);
    }

    private static async Task<IList<Conception>> FillConceptionAsync()
    {
        return await CommDataMethod<Conception>.GetDataOnDbSetAsync()
                                               .ConfigureAwait(false);
    }

    private async Task FillTreeViewDataAsync()
    {
        StocksNameTreeView.ItemsSource = await FillStockNameTreeAsync();
    }

    private static async Task<ObservableCollection<StockNameTree>> FillStockNameTreeAsync()
    {
        var _stockNameTrees = new ObservableCollection<StockNameTree>();
        var _conceptions = await FillConceptionAsync().ConfigureAwait(false);
        var _seleStocks = await FillSeleStocksAsync().ConfigureAwait(false);
        if (_conceptions.IsNullOrEmpty())
        {
            return _stockNameTrees;
        }

        foreach (var _rootItem in _conceptions)
        {
            var _stockNameTree = new StockNameTree
            {
                Parent = null,
                OrderID = _rootItem.OrderID,
                Name = _rootItem.Name,
                DisplayName = "■ " + (string.IsNullOrEmpty(_rootItem.Name) ? "其他" : _rootItem.Name)
            };
            foreach (var item in _seleStocks
                         .Where(n => n.Conception.Equals(_rootItem.Name)))
            {
                _stockNameTree.Children.Add(new StockNameTree
                {
                    Parent = _stockNameTree,
                    OrderID = item.OrderID,
                    Stock = item,
                    Name = item.Name,
                    DisplayName = "○ " + item.Name + "<" + item.Ts_code + ">"
                });
            }

            _stockNameTrees.Add(_stockNameTree);
        }

        _conceptions.Dispose();
        _seleStocks.Dispose();
        return _stockNameTrees;
    }

    private async void RefershTreeViewItem(object sender, SelectStock currentStock)
    {
        await FillTreeViewDataAsync();
        foreach (var item in StocksNameTreeView.Items)
        {
            if (item is not StockNameTree parentItem)
            {
                continue;
            }

            foreach (var childItem in parentItem.Children)
            {
                if (childItem.Stock.Ts_code.Equals(currentStock.Ts_code))
                {
                    var _parentContainer = StocksNameTreeView
                        .ItemContainerGenerator
                        .ContainerFromItem(item) as TreeViewItem;
                    //必须执行子节点的展开，否者后面查询总是为null,因为子节点不展开，视同不存在视觉元素
                    _parentContainer?.ExpandSubtree();
                    var _curItemContainer = _parentContainer
                        .ItemContainerGenerator
                        .ContainerFromItem(childItem) as TreeViewItem;
                    if (_curItemContainer is not null)
                    {
                        _curItemContainer.IsSelected = true;
                        _curItemContainer.Focus();
                    }
                }
            }
        }
    }

    //交换节点后，保存自选股的概念分类、排序ID值
    private async Task UpdateSeleStockOrderID(StockNameTree source, StockNameTree target)
    {
        if (target is null)
        {
            await CommDataMethod<SelectStock>.UpdateSeleStockAsync(
                ReCreatOrderIdAfterChanged(source).ToList());
            return;
        }
        await CommDataMethod<SelectStock>.UpdateSeleStockAsync(
            ReCreatOrderIdAfterChanged(source).Union(ReCreatOrderIdAfterChanged(target)).ToList());
    }

    private static IEnumerable<SelectStock> ReCreatOrderIdAfterChanged(StockNameTree itemParent)
    {
        var _index = 0;
        foreach (var item in itemParent.Children)
        {
            item.OrderID = $"{itemParent.OrderID}.{IntToString(_index++)}";
            item.Stock.Conception = itemParent.Name;
            item.Stock.OrderID = item.OrderID;
        }
        return itemParent.Children.Select(n => n.Stock);

        static string IntToString(int val)
        {
            return val < 10 ? $"0{val}" : $"{val}";
        }
    }

    private void TreeViewChangeStatus()
    {
        foreach (var item in StocksNameTreeView.Items)
        {
            var parentContainer = StocksNameTreeView
                .ItemContainerGenerator
                .ContainerFromItem(item) as TreeViewItem;
            if (parentContainer is not null)
            {
                parentContainer.IsExpanded = false;
            }
        }
    }

    private void TreeView_Change(object sender, RoutedEventArgs e)
    {
        var currTreeView = sender as TreeView;
        if (currTreeView.SelectedItem is StockNameTree selectItem)
        {
            //父节点为“分类概念”，不激活事件
            if (selectItem.Stock is null)
            {
                return;
            }

            ChartKline.ChangeCurrentStock(selectItem.Stock.Ts_code);
        }
    }

    /// <summary>
    ///     实现节点的自由移动位置
    /// </summary>

    #region

    private bool IsDrop;

    private StockNameTree moveTreeItem;

    private void TreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ChangedButton == MouseButton.Left)
        {
            var _currElement = e.OriginalSource as FrameworkElement;
            moveTreeItem = _currElement?.DataContext as StockNameTree;
        }
    }

    private void TreeView_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed
            && !IsDrop && moveTreeItem != null)
        {
            IsDrop = true;
            StocksNameTreeView.Cursor = Cursors.Hand;
        }
    }

    private void TreeView_MouseLeave(object sender, MouseEventArgs e)
    {
        ClearTreeDrop();
    }

    private void ClearTreeDrop()
    {
        moveTreeItem = null;
        IsDrop = false;
        StocksNameTreeView.Cursor = Cursors.Arrow;
    }

    private async void TreeView_MouseUp(object sender, MouseEventArgs e)
    {
        var targetTreeItem = (e.OriginalSource as FrameworkElement)
            .DataContext as StockNameTree;
        if (moveTreeItem?.Equals(targetTreeItem) ?? true)
        {
            goto Exit;
        }

        if (targetTreeItem.IsAdd)
        {
            //保存移动节点的父节点
            StockNameTree sourceParent, targetParent;
            sourceParent = moveTreeItem.Parent;
            //从移动节点的原集合中删除节点
            moveTreeItem.Parent.Children.Remove(moveTreeItem);
            //如果移动到一级节点，即概念分类节点，直接添加为新节点
            if (targetTreeItem.Parent is null)
            {
                moveTreeItem.Parent = targetTreeItem;
                targetTreeItem.Children.Add(moveTreeItem);
                targetParent = targetTreeItem;
            }
            else
            {
                moveTreeItem.Parent = targetTreeItem.Parent;
                targetParent = targetTreeItem.Parent;
                var _targetIndex = targetParent.Children.IndexOf(targetTreeItem);
                targetParent.Children.Insert(_targetIndex, moveTreeItem);
            }

            //在同一个分类节点下，只修订本分类节点下的全部子集的编号
            if (sourceParent.Equals(targetParent))
            {
                await UpdateSeleStockOrderID(sourceParent, null);
            }
            else //在不同分类节点下，修订原子集和新子集的编号
            {
                await UpdateSeleStockOrderID(sourceParent, targetParent);
            }

            targetTreeItem.IsAdd = false;
        }
    Exit:
        ClearTreeDrop();
    }

    private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
    {
        if (moveTreeItem is null || moveTreeItem.Parent is null)
        {
            return;
        }

        var currTreeItem = (e.OriginalSource as FrameworkElement)
            .DataContext as StockNameTree;
        if (moveTreeItem.Equals(currTreeItem))
        {
            return;
        }

        currTreeItem.IsAdd = IsDrop;
    }

    private void TextBlock_MouseLeave(object sender, MouseEventArgs e)
    {
        if (moveTreeItem is null || moveTreeItem.Parent is null)
        {
            return;
        }

        var currTreeItem = (e.OriginalSource as FrameworkElement)
            .DataContext as StockNameTree;
        currTreeItem.IsAdd = false;
    }
    #endregion
}

public class StockNameTree : INotifyPropertyChanged
{
    private bool _isAdd;
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public SelectStock Stock { get; set; }
    public string OrderID { get; set; }
    public StockNameTree Parent { get; set; }
    public ObservableCollection<StockNameTree> Children { get; set; } = new();
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    //拖动到目标节点时增加到同级目录标志 
    public bool IsAdd
    {
        get => _isAdd;
        set
        {
            if (_isAdd != value)
            {
                _isAdd = value;
                OnPropertyChanged(nameof(IsAdd));
            }
        }
    }
    public override bool Equals(object obj)
    {
        if (obj is not StockNameTree _item)
        {
            return false;
        }

        if (DisplayName == _item.DisplayName)
        {
            return true;
        }

        return false;
    }
    public override int GetHashCode()
    {
        return DisplayName.GetHashCode();
    }
}